package checkers3d.logic;

import java.awt.*;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.*;
import checkers3d.storage.*;
import checkers3d.presentation.*;
import java.util.logging.Level;
import javax.swing.JOptionPane;

/**
 * Allows for two players to login and start playing a scenario.
 *
 * @author Ruben Acuna
 */
public class MenuNewGameLoginMP extends GUIContainer
{
    /**
     * Y axis value along which buttons will be centered.
     */
    private final int CONTROL_BUTTON_AXIS = 500;

    /**
     * Name of the selected scenario.
     */
    private String scenarioName;

    /**
     * Reference the play button that the player clicks to start.
     */
    GUIButton buttonPlay;

    /**
     * GUI component for getting homes name.
     */
    GUITextbox loginHomeName;

    /**
     * GUI component for getting the homes password.
     */
    GUITextbox loginHomePassword;

    /**
     * GUI component that displays the homes validation state as a color.
     */
    GUILabel loginHomeValidation;

    /**
     * GUI component for getting visitors name.
     */
    GUITextbox loginVisitorName;

    /**
     * GUI component for getting the visitors password.
     */
    GUITextbox loginVisitorPassword;

    /**
     * GUI component that displays the visitors validation state as a color.
     */
    GUILabel loginVisitorValidation;

    public MenuNewGameLoginMP(Point size)
    {
        super(size);
        
        LinkedList<IDrawable> buttons = new LinkedList<IDrawable>();

        //add background image.
        add(new GUIPictureBox("Background.png", new Point()));

        //create the start button with behavior.
        //buttons.add(new GUIButton("button-start.png", null, new ObserverPlay(scenarioName)));
        buttonPlay = new GUIButton("button-start.png", null, new ObserverPlay());
        buttons.add(buttonPlay);

        //create the return button with behavior.
        buttons.add(new GUIButton("button-return.png", null, new ObserverReturn()));

        //add labels
        add(new GUILabel("Home Login", Color.WHITE, new Point(191, 250)));
        add(new GUILabel("Name:", Color.WHITE, new Point(124, 302)));
        add(new GUILabel("Password:", Color.WHITE, new Point(102, 322)));
        loginHomeValidation = new GUILabel("Account validated.", Color.RED, new Point(175, 270));
        add(loginHomeValidation);
        add(new GUILabel("Visitor Login", Color.WHITE, new Point(191 + 352, 250)));
        add(new GUILabel("Name:", Color.WHITE, new Point(124 + 352, 302)));
        add(new GUILabel("Password:", Color.WHITE, new Point(102 + 352, 322)));
        loginVisitorValidation = new GUILabel("Account validated.", Color.RED, new Point(175 + 352, 270));
        add(loginVisitorValidation);
        
        //add the textbox for both players name and password.
        loginHomeName = new GUITextbox(new Point(166, 300), 25, this);
        loginHomePassword = new GUITextbox(new Point(166, 320), 25, this);
        loginHomePassword.setSecure(true);
        loginVisitorName = new GUITextbox(new Point(166 + 352, 300), 25, this);
        loginVisitorPassword = new GUITextbox(new Point(166 + 352, 320), 25, this);
        loginVisitorPassword.setSecure(true);

        //add the buttons to the GUIContainer.
        for(IDrawable component : buttons)
            add(component);

        //compute the positions of the buttons
        UtilGUI.computeLayoutSpanning(getSize(), CONTROL_BUTTON_AXIS, buttons);
    }

    /**
     * Updates the validation state embedded in the color of the ready label.
     */
    public void validatePlayers() throws FileNotFoundException
    {
        try
        {
            String validatedPassword1 = DataManagerAccounts.getPlayerPassword(loginHomeName.getText());
            System.out.println(DataManagerAccounts.getPlayerPassword(loginHomeName.getText()));
            if(DataManagerAccounts.doesPlayerExist(loginHomeName.getText())
               && loginHomePassword.getText().equals(validatedPassword1)){
                  loginHomeValidation.setText("Account validated.");
                  loginHomeValidation.setDrawPosition(new Point(175, 270));
                  loginHomeValidation.setColor(Color.GREEN);
            }
            else
                loginHomeValidation.setColor(Color.RED);

            String validatedPassword2 = DataManagerAccounts.getPlayerPassword(loginVisitorName.getText());
            System.out.println(DataManagerAccounts.getPlayerPassword(loginVisitorName.getText()));
            if(DataManagerAccounts.doesPlayerExist(loginVisitorName.getText())
               && loginVisitorPassword.getText().equals(validatedPassword2)){
                  loginVisitorValidation.setText("Account validated.");
                  loginVisitorValidation.setDrawPosition(new Point(175 + 352, 270));
                  loginVisitorValidation.setColor(Color.GREEN);
            }
            else
                loginVisitorValidation.setColor(Color.RED);
        }
        catch(Exception error)
        {
            loginHomeValidation.setColor(Color.RED);
            loginVisitorValidation.setColor(Color.RED);
        }
    }

    /**
     * Handles a key press, when the GUIContainer is in focus, by sending it to
     * all of its components. If both players are validated, the start button is
     * enabled.
     *
     * @param  key       The character of the key that was pressed.
     */
    @Override
    public void onKeyPress(char key)
    {
        super.onKeyPress(key);

        try {
            validatePlayers();
        } catch (FileNotFoundException ex) {
            java.util.logging.Logger.getLogger(MenuNewGameLoginMP.class.getName()).log(Level.SEVERE, null, ex);
        }

        if(loginHomeValidation.getColor() == Color.GREEN
           && loginVisitorValidation.getColor() == Color.GREEN)
        {
            buttonPlay.setObserver(new ObserverPlay()); 
        }
        else
        {
            buttonPlay.setObserver(new ObserverNull());
        }
    }

    /**
     * Returns a string representation of this object containing it's class name.
     *
     * @return String representation.
     */
    @Override
    public String toString()
    {
        return getClass().getName();
    }
    
    /**
     * A observer for a button that creates and displays a new game object based
     * on the selected scenario.
     */
    private class ObserverPlay implements IInputObserver
    {
        /**
         * The home player.
         */
        private Player home;

        /**
         * The visitor player.
         */
        private Player visitor;

        /**
         * Class constructor that keeps a reference to the parent object.
         *
         * @param parent Reference to the parent MenuScenarioSelect object.
         */
        public ObserverPlay()
        {
            // Do nothing.
        }

        /**
         * Creates and displays a new game object based on the selected scenario.
         *
         * @param position Location of click within button.
         */
        public void onClick(Point position)
        {
            home = new Player(loginHomeName.getText(), loginHomePassword.getText());
            visitor = new Player(loginVisitorName.getText(), loginVisitorPassword.getText());
            
            String filename1 = (DataManagerGame.LOCATION_SAVEGAMES
                    + home.getName() + "&" + visitor.getName() + ".txt");

            System.out.println("The new file should be saved as: " +
                    filename1);
            try {
                DataManagerUtil.createFile(filename1);
                GameMaster.getInstance().removeTopGUIContainer();
                GameMaster.getInstance().addGUIContainer(new MenuGameSetup(getSize(), home, visitor));
            } catch (IOException ex) {
                JOptionPane.showMessageDialog(null, "Please create a folder called 'save' in the main directory.");
            }
        }

         /**
         * Key press observer that does nothing.
         *
         * @param key Key that was pressed.
         */
        public void onKeyPress(char key)
        {
            //do nothing.
        }
    }

    /**
     * A observer for a button that returns user to the scenario select screen.
     */
    private class ObserverReturn implements IInputObserver
    {
        /**
         * Returns the user to the scenario select screen.
         *
         * @param position Location of click within button.
         */
        public void onClick(Point position)
        {
            GameMaster.getInstance().removeTopGUIContainer();
        }

         /**
         * Key press observer that does nothing.
         *
         * @param key Key that was pressed.
         */
        public void onKeyPress(char key)
        {
            // Do nothing.
        }
    }

    /**
     * A observer for a button that does nothing.
     */
    private class ObserverNull implements IInputObserver
    {
        /**
         * Does nothing when a click happens.
         *
         * @param position Location of click within button.
         */
        public void onClick(Point position)
        {
            //do nothing.
        }

         /**
         * Key press observer that does nothing.
         *
         * @param key Key that was pressed.
         */
        public void onKeyPress(char key)
        {
            //do nothing.
        }
    }
}